/**
 * www.easyplatform.cn ©2016
 */
package cn.easyplatform.studio.web.editors.workbench;

import cn.easyplatform.entities.beans.table.TableBean;
import cn.easyplatform.entities.beans.table.TableField;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.StudioApp;
import cn.easyplatform.studio.cmd.biz.GetColumnNameCmd;
import cn.easyplatform.studio.cmd.biz.GetTableFieldCmd;
import cn.easyplatform.studio.cmd.biz.QueryCmd;
import cn.easyplatform.studio.cmd.biz.UpdateCmd;
import cn.easyplatform.studio.cmd.entity.GetEntityCmd;
import cn.easyplatform.studio.utils.WebUtils;
import cn.easyplatform.studio.vos.BizQueryVo;
import cn.easyplatform.studio.vos.FieldVo;
import cn.easyplatform.studio.vos.MessageVo;
import cn.easyplatform.studio.vos.TableFieldVo;
import cn.easyplatform.studio.web.editors.AbstractPanelEditor;
import cn.easyplatform.studio.web.layout.WorkbenchController;
import cn.easyplatform.type.FieldType;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zul.*;

import java.util.*;

/**
 * @author <a href="mailto:shiny_vc@163.com">陈云亮</a> <br/>
 * @since 2.0.0 <br/>
 */
public class I18nEditor extends AbstractPanelEditor {
    private enum EditStatus {
        EDIT_CREATE, EDIT_CREATE_CHANGE, EDIT_SELECT, EDIT_SELECT_CHANGE
    }

    private Bandbox search;

    private Combobox category;

    private Listbox tables;

    private Grid language;

    private Combobox status;

    private Combobox msg_type;

    private Textbox code;

    private Label rule_code;

    private Row ruleRow;

    private Toolbarbutton createBtn;

    private Toolbarbutton saveBtn;

    private Toolbarbutton deleteBtn;

    private List<TableFieldVo> tableFieldVoList;

    private Map<String, String> map = new HashMap<>();

    private EditStatus editStatus = EditStatus.EDIT_CREATE;

    private Map<String, String> selectMessage;

    private List<TableFieldVo> params = new ArrayList<>();

    private List<Textbox> textboxes = new ArrayList<>();
    /**
     * @param workbench
     * @param id
     */
    public I18nEditor(WorkbenchController workbench, String id) {
        super(workbench, id);
    }

    @Override
    public void create(Object... args) {
        Idspace is = createPanel(Labels.getLabel("menu.i18n"), "~./images/web.gif", "~./include/editor/workbench/i18n.zul");
        tables = (Listbox) is.getFellow("i18n_listbox_tables");
        search = (Bandbox) is.getFellow("i18n_bandbox_search");
        search.addEventListener(Events.ON_OK, this);
        search.addEventListener(Events.ON_OPEN, this);
        language = (Grid) is.getFellow("i18n_grid_language");
        category = (Combobox) is.getFellow("i18n_combobox_category");
        category.addEventListener(Events.ON_CHANGE, this);
        rule_code = (Label) is.getFellow("i18n_label_ruleCode");
        code = (Textbox) is.getFellow("i18n_textbox_code");
        code.addEventListener(Events.ON_CHANGE, this);
        status = (Combobox) is.getFellow("i18n_combobox_status");
        status.setValue((String) status.getItemAtIndex(0).getValue());
        status.addEventListener(Events.ON_CHANGE, this);
        msg_type = (Combobox) is.getFellow("i18n_combobox_msgType");
        msg_type.addEventListener(Events.ON_CHANGE, this);
        ruleRow = (Row) is.getFellow("rules");
        createBtn = (Toolbarbutton) is.getFellow("i18n_toolbarbutton_create");
        createBtn.addEventListener(Events.ON_CLICK, this);
        saveBtn = (Toolbarbutton) is.getFellow("i18n_toolbarbutton_save");
        saveBtn.addEventListener(Events.ON_CLICK, this);
        deleteBtn = (Toolbarbutton) is.getFellow("i18n_toolbarbutton_delete");
        deleteBtn.addEventListener(Events.ON_CLICK, this);
        putMapValue();
        rule_code.setValue(map.get(msg_type.getItemAtIndex(0).getValue()));
        boolean isMatch = false;
        //根据字段表设置多多国语言输入栏
        tableFieldVoList = StudioApp.execute(null, new GetTableFieldCmd("sys_message_info"));
        if (tableFieldVoList != null && tableFieldVoList.size() > 0) {
            for (TableFieldVo tableFieldVo : tableFieldVoList) {
                if (!tableFieldVo.getFieldName().toLowerCase().equals("status") && !tableFieldVo.getFieldName().toLowerCase().equals("msg_type") &&
                        !tableFieldVo.getFieldName().toLowerCase().equals("code")) {
                    Row row = new Row();
                    row.setValue(tableFieldVo);
                    row.appendChild(new Label(tableFieldVo.getFieldDes()));
                    Textbox textbox = new Textbox();
                    textbox.setId(tableFieldVo.getFieldName());
                    textbox.setPlaceholder(tableFieldVo.getFieldDes());
                    textbox.setWidth("200");
                    textbox.addEventListener(Events.ON_CHANGE, this);
                    params.add(tableFieldVo);
                    textboxes.add(textbox);
                    row.appendChild(textbox);
                    row.setParent(language.getRows());
                }
            }
            //获取标签表，判断字段表是否一致
            List<String> list = StudioApp.execute(new GetColumnNameCmd("sys_message_info"));
            if (list != null && list.size() == tableFieldVoList.size()) {
                for (int i = 0; i < list.size(); i++) {
                    if (list.get(i).equals(tableFieldVoList.get(i).getFieldName()))
                        isMatch = true;
                    else {
                        isMatch = false;
                        break;
                    }
                }
            }
        }

        if (isMatch == false)
            WebUtils.showError(Labels.getLabel("editor.I18n.noMatch.error"));
        /*TableBean e = (TableBean) StudioApp.execute(null, new GetEntityCmd("sys_message_info"));
        if (e != null && e.getFields() != null) {
            for (TableField tf : e.getFields()) {
                if (!tf.getName().equals("status") && !tf.getName().equals("msg_type") && !tf.getName().equals("code")) {
                    Row row = new Row();
                    row.setValue(tf);
                    row.appendChild(new Label(tf.getDescription()));
                    Textbox textbox = new Textbox();
                    textbox.setId(tf.getName());
                    textbox.setPlaceholder(tf.getDescription());
                    textbox.setWidth("200");
                    row.appendChild(textbox);
                    row.setParent(language.getRows());
                    //row.setDraggable(EntityType.TABLE.getName());
                }
            }
        }*/
        selectMessage = new HashMap<>();
        search(null,null);
        showHeaderBtns();
    }

    //页面列表生成
    private void createTables(List<Object[]> data) {
        List<Listitem> items = tables.getItems();
        for (Object[] ov : data) {
            Listitem ti = new Listitem();
            ti.appendChild(new Listcell(ov[0].toString()));
            ti.appendChild(new Listcell(ov[1].toString()));
            //ti.setDraggable("table");
            //setMessageTemp(ov);
            Map<String, String> map = new HashMap<>();
            for (int index = 0; index < ov.length; index++) {
                map.put(tableFieldVoList.get(index).getFieldName(), (String) ov[index]);
            }
            ti.setValue(map);
            ti.addEventListener(Events.ON_CLICK, this);
            items.add(ti);
        }
    }

    //页面输入框赋值
    private void setValue() {
        code.setReadonly(false);
        if (Strings.isBlank(selectMessage.get("code"))) {
            code.setValue(null);
            code.setDisabled(false);
            status.setValue(null);
            status.setSelectedIndex(0);
            status.setDisabled(false);
            status.setValue(status.getItemAtIndex(0).getLabel());
            msg_type.setSelectedIndex(0);
            msg_type.setValue(msg_type.getItemAtIndex(0).getLabel());
            msg_type.setDisabled(false);
            ruleRow.setVisible(true);
            rule_code.setValue(map.get(msg_type.getItemAtIndex(0).getValue()));
        } else {
            code.setValue(selectMessage.get("code"));
            code.setDisabled(true);
            ruleRow.setVisible(false);

            boolean isInItem = false;
            if (Strings.isBlank(selectMessage.get("status")) == false) {
                for (Comboitem ci : status.getItems()) {
                    if (ci.getValue().equals(selectMessage.get("status"))) {
                        status.setSelectedItem(ci);
                        isInItem = true;
                        break;
                    }
                }
            }
            if (isInItem == false)
                status.setSelectedIndex(2);

            boolean isInTypeItem = false;
            if (Strings.isBlank(selectMessage.get("msg_type")) == false) {
                for (Comboitem ci : msg_type.getItems()) {
                    if (ci.getValue().equals(selectMessage.get("msg_type"))) {
                        msg_type.setSelectedItem(ci);
                        isInTypeItem = true;
                        break;
                    }
                }
            }
            if (isInTypeItem == false)
               msg_type.setSelectedIndex(12);
        }

        for (int i = 0; i < params.size(); i++) {
            textboxes.get(i).setValue(selectMessage.get(params.get(i).getFieldName()));
        }
        /*zh_cn.setValue(selectMessage.getZh_cn());
        zh_tw.setValue(selectMessage.getZh_tw());
        en_us.setValue(selectMessage.getEn_us());
        ja_jp.setValue(selectMessage.getJa_jp());
        ko_kr.setValue(selectMessage.getKo_kr());
        de_de.setValue(selectMessage.getDe_de());
        fr_fr.setValue(selectMessage.getFr_fr());
        it_it.setValue(selectMessage.getIt_it());*/
    }

    //获取页面输入框的值
    private void setMessage() {
        selectMessage.put("code", code.getValue());
        for (int i = 0; i < params.size(); i++) {
            selectMessage.put(params.get(i).getFieldName(), textboxes.get(i).getValue());
        }
        /*selectMessage.setZh_cn(zh_cn.getValue());
        selectMessage.setZh_tw(zh_tw.getValue());
        selectMessage.setEn_us(en_us.getValue());
        selectMessage.setJa_jp(ja_jp.getValue());
        selectMessage.setKo_kr(ko_kr.getValue());
        selectMessage.setDe_de(de_de.getValue());
        selectMessage.setFr_fr(fr_fr.getValue());
        selectMessage.setIt_it(it_it.getValue());*/
        if (status.getSelectedItem() != null)
            selectMessage.put("status", status.getSelectedItem().getValue().toString());
        if (msg_type.getSelectedItem() != null)
            selectMessage.put("msg_type", msg_type.getSelectedItem().getValue().toString());
    }

    //页面事件监听
    @Override
    public void dispatch(Event event) {
        Component c = event.getTarget();
        if (event.getTarget() instanceof Listitem) {
            final Listitem row = (Listitem) event.getTarget();
            //列表行点击
            if (editStatus == EditStatus.EDIT_SELECT_CHANGE || editStatus == EditStatus.EDIT_CREATE_CHANGE)
                WebUtils.showConfirm(Labels.getLabel("button.save"), new EventListener<Event>() {
                    @Override
                    public void onEvent(Event event) throws Exception {
                        if (event.getName().equals(Events.ON_OK))
                            Events.postEvent(new Event(Events.ON_CLICK, saveBtn));
                        else {
                            selectMessage = row.getValue();
                            editStatus = EditStatus.EDIT_SELECT;
                            showHeaderBtns();
                            setValue();
                        }
                    }
                });
            else {
                selectMessage = row.getValue();
                editStatus = EditStatus.EDIT_SELECT;
                showHeaderBtns();
                setValue();
            }
        } else if (event.getTarget().getId().equals("i18n_combobox_category")) { //查询类别
            selectMessage = new HashMap<>();
            setValue();
            search(category.getSelectedItem().getValue().toString(), search.getValue());
        } else if (event.getTarget().getId().equals("i18n_combobox_msgType")) { //选择类型
            rule_code.setValue(map.get(msg_type.getSelectedItem().getValue()));
            if (editStatus == EditStatus.EDIT_SELECT) {
                editStatus = EditStatus.EDIT_SELECT_CHANGE;
                showHeaderBtns();
            }
        } else if (event.getTarget().getId().equals("i18n_combobox_status")) { //选择类型
            if (editStatus == EditStatus.EDIT_SELECT) {
                editStatus = EditStatus.EDIT_SELECT_CHANGE;
                showHeaderBtns();
            }
        } else if (event.getTarget().getId().equals("i18n_toolbarbutton_create")) {//新增按钮
            if (editStatus == EditStatus.EDIT_SELECT_CHANGE || editStatus == EditStatus.EDIT_CREATE_CHANGE)
                WebUtils.showConfirm(Labels.getLabel("button.save"), new EventListener<Event>() {
                    @Override
                    public void onEvent(Event event) throws Exception {
                        if (event.getName().equals(Events.ON_OK))
                            Events.postEvent(new Event(Events.ON_CLICK, saveBtn));
                        else {
                            editStatus = EditStatus.EDIT_CREATE;
                            showHeaderBtns();
                            selectMessage = new HashMap<>();
                            setValue();
                        }
                    }
                });
            else {
                editStatus = EditStatus.EDIT_CREATE;
                showHeaderBtns();
                selectMessage = new HashMap<>();
                setValue();
            }
        } else if (event.getTarget() instanceof Textbox && event.getName().equals(Events.ON_CHANGE)) {
            if (editStatus == EditStatus.EDIT_CREATE)
                editStatus = EditStatus.EDIT_CREATE_CHANGE;
            else if (editStatus == EditStatus.EDIT_SELECT)
                editStatus = EditStatus.EDIT_SELECT_CHANGE;
            showHeaderBtns();
        } else if (event.getTarget().getId().equals("i18n_toolbarbutton_save")) { //保存按钮

            if (code.getValue().equals("")) {
                code.setFocus(true);
                throw new WrongValueException(code, Labels.getLabel(
                        "message.no.empty", new Object[]{Labels.getLabel("navi.entity")}));
            } else if (textboxes.get(0).getValue().equals("")) {
                textboxes.get(0).setFocus(true);
                throw new WrongValueException(textboxes.get(0), Labels.getLabel(
                            "message.no.empty", new Object[]{Labels.getLabel("navi.entity")}));
            } else if (selectMessage.get("code") == null) {
                setMessage();
                StringBuffer sqlBuffer = new StringBuffer("insert into sys_message_info(code,");
                for (TableFieldVo fieldVo : params) {
                    sqlBuffer.append(fieldVo.getFieldName()).append(",");
                }
                sqlBuffer.append("status,MSG_TYPE) values (");
                for (int i = 0; i < params.size() + 3; i++) {
                    sqlBuffer.append("?,");
                }
                sqlBuffer.deleteCharAt(sqlBuffer.length() - 1);
                sqlBuffer.append(")");
                List<FieldVo> sqlParams = new ArrayList<>();
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.get("code")));
                for (TableFieldVo key: params) {
                    sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.get(key.getFieldName())));
                }
                //sqlstr = "insert into sys_message_info(code,zh_cn,zh_tw,en_us,ja_jp,ko_kr,de_de,fr_fr,it_it,status,MSG_TYPE) values (?,?,?,?,?,?,?,?,?,?,?)";
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.get("status")));
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.get("msg_type")));
                Boolean upflag = false;
                try {
                    upflag = StudioApp.execute(new UpdateCmd(sqlBuffer.toString(), sqlParams));
                } catch (Exception e) {
                    WebUtils.showInfo(Labels.getLabel("message.code.exist"));
                    return;
                }
                if (upflag) {
                    WebUtils.showSuccess(Labels.getLabel("button.save"));
                    search(category.getSelectedItem().getValue().toString(), search.getValue());
                    code.setReadonly(true);
                    editStatus = EditStatus.EDIT_CREATE;
                    showHeaderBtns();
                } else {
                    selectMessage = new HashMap<>();
                    WebUtils.showError(Labels.getLabel("message.error", new String[]{Labels.getLabel("button.save")}));
                    return;
                }
            } else {
                setMessage();
                StringBuffer sqlBuffer = new StringBuffer("update sys_message_info set ");
                for (TableFieldVo fieldVo : params) {
                    sqlBuffer.append(fieldVo.getFieldName()).append("=?,");
                }
                sqlBuffer.append("status=?,MSG_TYPE=? where code=?");
                List<FieldVo> sqlParams = new ArrayList<>();
                for (TableFieldVo key: params) {
                    sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.get(key.getFieldName())));
                }
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.get("status")));
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.get("msg_type")));
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.get("code")));
                if (StudioApp.execute(new UpdateCmd(sqlBuffer.toString(), sqlParams))) {
                    WebUtils.showSuccess(Labels.getLabel("button.save"));
                    search(category.getSelectedItem().getValue().toString(), search.getValue());
                    editStatus = EditStatus.EDIT_SELECT;
                    showHeaderBtns();
                } else {
                    WebUtils.showError(Labels.getLabel("message.error", new String[]{Labels.getLabel("button.save")}));
                }
                /*sqlstr = "update sys_message_info set zh_cn=?,zh_tw=?,en_us=?,ja_jp=?,ko_kr=?,de_de=?,fr_fr=?,it_it=?,status=?,MSG_TYPE=? where code=?";
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.getZh_cn()));
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.getZh_tw()));
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.getEn_us()));
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.getJa_jp()));
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.getKo_kr()));
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.getDe_de()));
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.getFr_fr()));
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.getIt_it()));
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.getStatus()));
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.getMSG_TYPE()));
                sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.getCode()));
                if (StudioApp.execute(new UpdateCmd(sqlstr, sqlParams))) {
                    WebUtils.showSuccess(Labels.getLabel("button.save"));
                    search(category.getSelectedItem().getValue().toString(), search.getValue());
                    editStatus = EditStatus.EDIT_SELECT;
                    showHeaderBtns();
                } else {
                    WebUtils.showError(Labels.getLabel("message.error", new String[]{Labels.getLabel("button.save")}));
                }*/
            }
        } else if (event.getTarget().getId().equals("i18n_toolbarbutton_delete")) { //删除按钮
            if (selectMessage.get("code") == null) {
                WebUtils.showError(Labels.getLabel("editor.select",
                        new String[]{Labels.getLabel("navi.entity")}));
                return;
            }
            WebUtils.showConfirm(Labels.getLabel("button.delete"), new EventListener<Event>() {
                @Override
                public void onEvent(Event event) throws Exception {
                    if (event.getName().equals(Events.ON_OK)) {
                        String sqlstr = "delete from sys_message_info where code=?";
                        List<FieldVo> sqlParams = new ArrayList<>();
                        sqlParams.add(new FieldVo(FieldType.VARCHAR, selectMessage.get("code")));
                        if (StudioApp.execute(new UpdateCmd(sqlstr, sqlParams))) {
                            getSelectedRow().detach();
                            search(category.getSelectedItem().getValue().toString(), search.getValue());
                            selectMessage = new HashMap<>();
                            setValue();
                            editStatus = EditStatus.EDIT_CREATE;
                            showHeaderBtns();
                        }
                    }
                }
            });
        } else if (c instanceof Bandbox) { //搜索框
            selectMessage = new HashMap<>();
            setValue();
            String val = null;
            if (event instanceof OpenEvent) {
                OpenEvent evt = (OpenEvent) event;
                val = (String) evt.getValue();
                search.setValue(val);
            } else {
                val = search.getValue();
            }
            search(category.getSelectedItem().getValue().toString(), val);
        } else if (event.getTarget().getId().equals("cancel")) {
            if (editStatus == EditStatus.EDIT_CREATE_CHANGE) {
                selectMessage = new HashMap<>();
                setValue();
                editStatus = EditStatus.EDIT_CREATE;
                showHeaderBtns();
            }
            else if (editStatus == EditStatus.EDIT_SELECT_CHANGE) {
                setValue();
                editStatus = EditStatus.EDIT_SELECT;
                showHeaderBtns();
            }
        }
    }

    private void search(String type, String val) {
        BizQueryVo biz = new BizQueryVo();
        if (Strings.isBlank(type)) {
            if (Strings.isBlank(val)) {
                biz.setSql("select * from sys_message_info where 1=1");
            } else {
                biz.setSql("select * from sys_message_info where 1=1 and (code like '%"+val+"%' or zh_cn like '%"+val+"%')");
            }
        } else {
            if (Strings.isBlank(val)) {
                biz.setSql("select * from sys_message_info where 1=1 and MSG_TYPE='"+type+"'");
            } else {
                biz.setSql("select * from sys_message_info where 1=1 and MSG_TYPE='"+type+"' and (code like '%"+val+"%' or zh_cn like '%"+val+"%')");
            }
        }
        tables.getItems().removeAll(tables.getItems());
        List<Object[]> cp = StudioApp.execute(new QueryCmd(biz, 100)).getResult().getData();
        createTables(cp);
    }

    private Listitem getSelectedRow() {
        if (selectMessage == null)
            return null;
        return tables.getSelectedItem();
    }

    private void putMapValue() {
        map.put("H", "I/i，E/e，W/w，C/c，P/p，L_, B_，M_，C_，R_，O "+Labels.getLabel("message.begin.except"));
        map.put("I", "I/i "+Labels.getLabel("message.begin"));
        map.put("E", "E/e "+Labels.getLabel("message.begin"));
        map.put("W", "W/w "+Labels.getLabel("message.begin"));
        map.put("C", "C/c "+Labels.getLabel("message.begin"));
        map.put("P", "P/p "+Labels.getLabel("message.begin"));
        map.put("L", "L_ "+Labels.getLabel("message.begin"));
        map.put("B", "B_ "+Labels.getLabel("message.begin"));
        map.put("M", "M_ "+Labels.getLabel("message.begin"));
        map.put("F", "C_ "+Labels.getLabel("message.begin"));
        map.put("R", "R_ "+Labels.getLabel("message.begin"));
        map.put("O", "O "+Labels.getLabel("message.begin"));
    }

    private void showHeaderBtns() {
        if (editStatus == EditStatus.EDIT_CREATE) {
            saveBtn.setDisabled(true);
            deleteBtn.setDisabled(true);
        } else if (editStatus == EditStatus.EDIT_CREATE_CHANGE || editStatus == EditStatus.EDIT_SELECT_CHANGE) {
            saveBtn.setDisabled(false);
            deleteBtn.setDisabled(true);
        } else if (editStatus == EditStatus.EDIT_SELECT) {
            saveBtn.setDisabled(true);
            deleteBtn.setDisabled(false);
        }
    }
}
